/* Copyright 2008. All rights reserved. */
package org.bling.parser.tags;

import java.util.Iterator;

import org.apache.commons.jexl.Expression;
import org.apache.commons.jexl.ExpressionFactory;
import org.apache.commons.jexl.JexlContext;
import org.apache.commons.jexl.JexlHelper;
import org.bling.parser.BlingParserException;
import org.bling.process.context.ScreenContext;
import org.eclipse.swt.widgets.Widget;

/**
 * 
 * <code>Tag</code> - similar to JSP tags, Bling tags allow XML to be
 * converted into SWT widgets.
 * 
 * @author DISBROB
 * 
 */
public abstract class Tag {

	protected Tag parent = null;
	protected String bodyContent = "";
	protected ScreenContext context;

	public void setContext(ScreenContext context) {
		this.context = context;
	}

	public void setParent(Tag parent) {
		this.parent = parent;
	}

	public String getBodyContent() {
		return bodyContent;
	}

	public void setBodyContent(String bodyContent) {
		this.bodyContent = bodyContent;
	}

	/**
	 * Skip body evaluation. Valid return value for doStartTag and doAfterBody.
	 */

	public final static int SKIP_BODY = 0;

	/**
	 * Evaluate body again. Used for creating iteration tags. Valid return value for
	 * doAfterBody.
	 */

	public final static int EVAL_BODY_AGAIN = 1;

	/**
	 * Skip the rest of the page. Valid return value for doEndTag.
	 */

	public final static int SKIP_PAGE = 5;

	/**
	 * Continue evaluating the page. Valid return value for doEndTag().
	 */

	public final static int EVAL_PAGE = 6;

	public int doStartTag() throws BlingParserException {
		return SKIP_BODY;
	}

	public int doEndTag() throws BlingParserException {
		return EVAL_PAGE;
	}

	public int doAfterBody() throws BlingParserException {
		return SKIP_BODY;
	}

	public abstract Widget getWidget() throws BlingParserException;

	public Object evaluate(String expression) {
		try {
			Expression e = ExpressionFactory.createExpression(expression);
			JexlContext jc = toContext(context);
			Object value = e.evaluate(jc);
			return value;
		} catch (Exception e) {
			return null;
		}
	}
	
	private JexlContext toContext(ScreenContext context) {
		JexlContext jc = JexlHelper.createContext();
		
		Iterator<String> keys = context.keySet().iterator();
		while (keys.hasNext()) {
			String key = keys.next();
			jc.getVars().put(key, context.getAttribute(key));
		}
		
		return jc;
	}
}
